package com.zsummer.zero.design.create.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 原型模式
 * @author zhouyujiang
 *
 */
public class Start {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		//new Start().run1();
		new Start().run2();
	}
	

	/**
	 * 浅拷贝
	 */
	void run1() {
		Man man = new Man();
		man.setName("周俞江");
		man.setAge((short) 18);
		Son son = new Son();
		son.setName("小儿子");
		man.setSon(son);
		try {
			Man cloneMan = (Man) man.clone();
			System.out.println(man);
			System.out.println(cloneMan);
			
			man.setAge((short) 19);
			man.setName("大海");
			man.getSon().setName("大儿子");
//			man.setSon(new Son());
			
			System.out.println(man);
			System.out.println(cloneMan);
			System.out.println(man.getSon().getName());
			System.out.println(cloneMan.getSon().getName());
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 使用序列化进行深拷贝
	 * @throws IOException 
	 * @throws ClassNotFoundException 
	 */
	private void run2() throws IOException, ClassNotFoundException {
		Man man = new Man();
		man.setName("周俞江");
		man.setAge((short) 18);
		Son son = new Son();
		son.setName("小儿子");
		man.setSon(son);
		
		// 将对象写入流中
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		oos.writeObject(man);
		oos.flush();
		
		// 从流中读出
		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bais);
		Man deepCloneMan = (Man) ois.readObject();
		
		oos.close();
		baos.close();
		ois.close();
		bais.close();
		
		System.out.println(man + "@" + Integer.toHexString(deepCloneMan.hashCode()));
		System.out.println(deepCloneMan + "@" + Integer.toHexString(deepCloneMan.hashCode()));
		
		man.getSon().setName("大儿子");
		deepCloneMan.getSon().setName("小儿子");
		
		System.out.println(man.getSon().getName());
		System.out.println(deepCloneMan.getSon().getName());
		
	}
}
